package com.match.competition_sub.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.match.commonutils.JwtUtils;
import com.match.commonutils.MD5;
import com.match.commonutils.Result;
import com.match.competition_sub.client.MainClient;
import com.match.competition_sub.entity.*;
import com.match.competition_sub.entity.vo.StuQuery;
import com.match.competition_sub.entity.vo.StudentCreditVo;
import com.match.competition_sub.service.CompetitionDepartmentService;
import com.match.competition_sub.service.StudentCourseNumberService;
import com.match.competition_sub.service.StudentNumberGroutidService;
import com.match.competition_sub.service.StudentService;
import com.match.entity.Vo.UserRoleVo;
import com.match.entity.roleEntity.CompetitionRole;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author AdiosF
 * @since 2021-09-21
 */
@Api(tags = "学生模块")
@RestController
@RequestMapping("/competition_sub/student")
public class StudentController{
    BCryptPasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
    @Autowired
    private StudentService studentService;
    @Autowired
    private CompetitionDepartmentService competitionDepartmentService;
    @Autowired
    private MainClient mainClient;
    @Autowired
    private StudentNumberGroutidService studentNumberGroutidService;
    @Autowired
    private StudentCourseNumberService studentCourseNumberService;


    @ApiOperation("EasyExcel录入学生数据")
    @PostMapping("/addStuByExcel")
    public Result addStuByExcel(@RequestBody(required = false) MultipartFile file){
        if (file==null){
            return Result.error().message("请先选择好文件再上传!");
        }
        studentService.addStuByExcel(file,studentService);

        //添加系别以及专业
        QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.select("distinct lever,major_nam");
        List<Student> studentList = studentService.list(studentQueryWrapper);
        for (Student student : studentList) {
            //查询一级是否存在
            QueryWrapper<CompetitionDepartment> oneQuery=new QueryWrapper<>();
            oneQuery.eq("department",student.getLever());
            CompetitionDepartment one = competitionDepartmentService.getOne(oneQuery);
            if (StringUtils.isEmpty(one)){
                //添加一级
                CompetitionDepartment competitionDepartment=new CompetitionDepartment();
                competitionDepartment.setDepartment(student.getLever());
                competitionDepartment.setParentId("0");
                competitionDepartmentService.save(competitionDepartment);
                //添加二级
                QueryWrapper<CompetitionDepartment> competitionDepartmentQueryWrapper=new QueryWrapper<>();
                competitionDepartmentQueryWrapper.eq("department",student.getLever());
                CompetitionDepartment one1 = competitionDepartmentService.getOne(competitionDepartmentQueryWrapper);
                CompetitionDepartment twoDepartment=new CompetitionDepartment();
                twoDepartment.setDepartment(student.getMajorNam());
                twoDepartment.setParentId(one1.getId());
                competitionDepartmentService.save(twoDepartment);
            }else {
                //判断二级是否存在
                QueryWrapper<CompetitionDepartment> twoQuery=new QueryWrapper<>();
                twoQuery.eq("department",student.getMajorNam());
                CompetitionDepartment two = competitionDepartmentService.getOne(twoQuery);
                if (StringUtils.isEmpty(two)){
                    CompetitionDepartment competitionDepartment=new CompetitionDepartment();
                    competitionDepartment.setDepartment(student.getMajorNam());
                    competitionDepartment.setParentId(one.getId());
                    competitionDepartmentService.save(competitionDepartment);
                    continue;
                }
                continue;
            }
        }
        return Result.ok().message("成功");
    }



    @ApiOperation("添加学生接口")
    @PostMapping("/addStu")
    public Result addStu(@RequestBody Student student){
        //根据学生学号查重
        QueryWrapper<Student> queryWrapper=new QueryWrapper<>();
        if (!StringUtils.isEmpty(student.getNumber())){
            queryWrapper.eq("number",student.getNumber());
            Student studentNumber = studentService.getOne(queryWrapper);
            if (!StringUtils.isEmpty(studentNumber)){
                return Result.error().message("学号不可重复");
            }
        }
        if (!StringUtils.isEmpty(student.getPhone())){
            QueryWrapper<Student> studentQueryWrapper=new QueryWrapper<>();
            studentQueryWrapper.eq("phone",student.getPhone());
            Student studentPhone = studentService.getOne(studentQueryWrapper);
            if (!StringUtils.isEmpty(studentPhone)){
                return Result.error().message("手机号不可重复");
            }
        }
        //密码进行MD5加盐加密
        student.setPassword(passwordEncoder.encode(student.getPassword()));
        studentService.save(student);
        return Result.ok().message("添加成功");
    }


    @ApiOperation("学生-修改密码")
    @PostMapping("/updatePassword")
    public Result updatePassword(@RequestBody Student student){
        QueryWrapper<Student> studentQueryWrapper=new QueryWrapper<>();
        studentQueryWrapper.eq("number",student.getNumber());
        Student one = studentService.getOne(studentQueryWrapper);
        one.setPassword(passwordEncoder.encode(student.getPassword()));
        studentService.updateById(one);
        return Result.ok();
    }


    @ApiOperation("根据学生学号删除学生信息")
    @DeleteMapping("/deleteByStuNum/{number}")
    public Result deleteByStuNum(@ApiParam(required = true,value = "学号")
                            @PathVariable(value = "number") String number){
        QueryWrapper<Student> studentQueryWrapper=new QueryWrapper<>();
        studentQueryWrapper.eq("number",number);
        boolean b = studentService.remove(studentQueryWrapper);
        if (b){
            return Result.ok();
        }else {
            return Result.error();
        }
    }


    @ApiOperation("根据学生学号更新学生状态接口")
    @PostMapping("/updateStuState/{stuNum}/{state}")
    public Result updateStuState(@ApiParam(required = true,value = "学生学号")
                            @PathVariable String stuNum,
                                 @PathVariable int state){
        Boolean b=studentService.updateStuState(stuNum,state);
        return Result.ok();
    }



    @ApiOperation("学生分页条件查询接口")
    @PostMapping("/findStuByQuery/{current}/{limit}")
    public Result findStuByQuery(@ApiParam(value = "当前页")
                            @PathVariable(required = true) long current,
                                 @ApiParam(value = "每页记录数")
                            @PathVariable(required = true) long limit,
                                 @RequestBody(required = false) StuQuery stuQuery){
        Map<String,Object> map=studentService.findStuByQuery(current,limit,stuQuery);
        Long total = (Long) map.get("total");
        List<Student> records = (List<Student>) map.get("records");
        return Result.ok().data("total",total).data("records",records).message("数据查询成功");
    }



    @ApiOperation("根据学生学号查询学生信息接口")
    //@Cacheable(value = "student",key = "'studentInfo'")
    @GetMapping("/findStuByNum/{number}")
    public Result findStuByNum(@ApiParam(value = "学号")
                          @PathVariable String number){
        QueryWrapper<Student> studentQueryWrapper=new QueryWrapper<>();
        studentQueryWrapper.eq("number",number);
        Student one = studentService.getOne(studentQueryWrapper);
        return Result.ok().data("stuInfo",one);
    }


    @ApiOperation("学生-根据学生学号查询学生信息接口")
    @GetMapping("/getStuByNum/{number}")
    public Result getStuByNum(@ApiParam(value = "学号")
                               @PathVariable String number){
        QueryWrapper<Student> studentQueryWrapper=new QueryWrapper<>();
        studentQueryWrapper.eq("number",number).select("lever,grade,major_nam");
        Student one = studentService.getOne(studentQueryWrapper);
        return Result.ok().data("stuInfo",one);
    }


    @ApiOperation("根据学生学号修改学生信息")
    @PostMapping("/updateByStuId")
    public Result updateByStuNum(@RequestBody Student student){
        Student sqlStudent = studentService.getById(student.getId());
        //判断前端修改与数据库是否相同
        if (!student.equals(sqlStudent)){
            //校验学号
            if (!student.getNumber().equals(sqlStudent.getNumber())){
                QueryWrapper<Student> studentQueryWrapper=new QueryWrapper<>();
                studentQueryWrapper.eq("number",student.getNumber());
                int count = studentService.count(studentQueryWrapper);
                if (count==1){
                    return Result.error().message("学号已存在");
                }
            }
            //校验手机号
            if (!student.getPhone().equals(sqlStudent.getPhone())){
                QueryWrapper<Student> studentQueryWrapper=new QueryWrapper<>();
                studentQueryWrapper.eq("phone",student.getPhone());
                int count = studentService.count(studentQueryWrapper);
                if (count==1){
                    return Result.error().message("手机号已存在");
                }
            }
            //校验密码是否变化
            if (!student.getPassword().equals(sqlStudent.getPassword())){
                //对密码进行加密
                student.setPassword(passwordEncoder.encode(student.getPassword()));
            }
        }else {
            return Result.error().message("您暂未做任何修改");
        }
        studentService.updateById(student);
        return Result.ok().message("信息修改成功");
    }


    @ApiOperation("获得所有学生")
    @GetMapping("/getAllEntryStudent")
    public Result getAllEntryStudent(){
        QueryWrapper<Student> studentQueryWrapper=new QueryWrapper<>();
        studentQueryWrapper.select("number,name");
        List<Student> list = studentService.list(studentQueryWrapper);
        return Result.ok().data("allStudent",list);
    }


    @ApiOperation("为学生分配角色")
    @PostMapping("/assignRoleToStudent")
    public Result assignRoleToStudent(@RequestBody Map<String,Object> map){
        String groupId = (String) map.get("groupId");
        List<String> studentId = (List<String>) map.get("studentId");
        String leaderId= (String) map.get("leaderId");
        if (!StringUtils.isEmpty(leaderId)){
            //为此学生分配角色为队长
            Object roleList = mainClient.getOneRoleByQuery("队长").getData().get("role");
            String s = JSON.toJSONString(roleList);
            CompetitionRole competitionRole = JSON.parseObject(s, CompetitionRole.class);
            StudentNumberGroutid studentNumberGroutid=new StudentNumberGroutid();
            studentNumberGroutid.setGroutId(groupId);
            studentNumberGroutid.setStudentNumber(leaderId);
            studentNumberGroutid.setRoleId(competitionRole.getId());
            studentNumberGroutidService.save(studentNumberGroutid);
            Student one = studentService.getOne(new QueryWrapper<Student>().eq("number", leaderId));
            one.setRole(competitionRole.getRoleName());
            one.setCounterNumber(one.getCounterNumber()+1);
            studentService.updateById(one);
        }
        if (studentId.size()>0){
            for (String s : studentId) {
                //为此学生分配角色为参赛学生
                Object roleList = mainClient.getOneRoleByQuery("参赛学生").getData().get("role");
                String string = JSON.toJSONString(roleList);
                CompetitionRole competitionRole = JSON.parseObject(string, CompetitionRole.class);
                StudentNumberGroutid studentNumberGroutid=new StudentNumberGroutid();
                studentNumberGroutid.setRoleId(competitionRole.getId());
                studentNumberGroutid.setGroutId(groupId);
                studentNumberGroutid.setStudentNumber(s);
                studentNumberGroutidService.save(studentNumberGroutid);
                Student one = studentService.getOne(new QueryWrapper<Student>().eq("number", s));
                one.setRole(competitionRole.getRoleName());
                one.setCounterNumber(one.getCounterNumber()+1);
                studentService.updateById(one);
            }
        }
        return Result.ok();
    }


    @ApiOperation("获得参赛组员")
    @GetMapping("/getAllMembers/{leaderId}")
    public Result getAllMembers(@PathVariable(value = "leaderId")String leaderId){
        QueryWrapper<Student> studentQueryWrapper=new QueryWrapper<>();
        studentQueryWrapper.notIn("number",leaderId);
        List<Student> list = studentService.list(studentQueryWrapper);
        return Result.ok().data("groupMembersLists",list);
    }


    @ApiOperation("根据组别ID获取学生集合")
    @GetMapping("/getStudentByGrout/{groutId}")
    public Result  getStudentByGrout(@PathVariable(value = "groutId") String groutId){
        QueryWrapper<StudentNumberGroutid> studentNumberGroutidQueryWrapper=new QueryWrapper<>();
        studentNumberGroutidQueryWrapper.eq("grout_id",groutId);
        List<StudentNumberGroutid> list = studentNumberGroutidService.list(studentNumberGroutidQueryWrapper);
        List<Student> students=new ArrayList<>();
        for (StudentNumberGroutid studentNumberGroutid : list) {
            QueryWrapper<Student> studentQueryWrapper=new QueryWrapper<>();
            studentQueryWrapper.eq("number",studentNumberGroutid.getStudentNumber());
            Student student = studentService.getOne(studentQueryWrapper);
            student.setStudentCredit(Integer.parseInt(studentNumberGroutid.getAffirmCredit()));
            student.setIsorReplace(studentNumberGroutid.getIsorReplace());
            student.setPassword("null");
            student.setPhone("null");
            student.setState(0);
            student.setId("null");
            students.add(student);
        }
        return Result.ok().data("studentList",students);
    }


    @ApiOperation("判断全部学生是否已置换")
    @GetMapping("/replacementOfCredit/{groutId}")
    public Result replacementOfCredit(@PathVariable(value = "groutId") String groutId){
        QueryWrapper<StudentNumberGroutid> studentNumberGroutidQueryWrapper=new QueryWrapper<>();
        studentNumberGroutidQueryWrapper.eq("grout_id",groutId);
        List<StudentNumberGroutid> list = studentNumberGroutidService.list(studentNumberGroutidQueryWrapper);
        for (StudentNumberGroutid studentNumberGroutid : list) {
            if (studentNumberGroutid.getIsorReplace().equals(0)){
                return Result.ok().data("result",false);
            }
        }
        //更新报名状态
        studentService.updateSignUpState(groutId,1,7);
        return Result.ok().data("result",true);
    }


    @ApiOperation("添加认证学分")
    @GetMapping("/updateStudentCredit/{groutId}/{affirmCredit}")
    public Result updateStudentCredit(@ApiParam(value = "组别Id") @PathVariable(value = "groutId") String groutId,
                                      @ApiParam(value ="认证学分") @PathVariable(value = "affirmCredit") String affirmCredit){
        Boolean result=studentNumberGroutidService.updateStudentCredit(groutId,affirmCredit);
        if (result){
            return Result.ok();
        }else {
            return Result.error().message("更新学生学分认证失败");
        }
    }


    @ApiOperation("获取学生的学分信息")
    @GetMapping("/getStudentCredit/{studentNumber}/{groutId}")
    public Result getStudentCredit(@PathVariable(value = "studentNumber")String studentNumber,
                                   @PathVariable(value = "groutId")String groutId){
        QueryWrapper<StudentNumberGroutid> studentNumberGroutidQueryWrapper=new QueryWrapper<>();
        if (!StringUtils.isEmpty(groutId)){
            studentNumberGroutidQueryWrapper.eq("grout_id",groutId);
        }
        if (!StringUtils.isEmpty(studentNumber)){
            studentNumberGroutidQueryWrapper.eq("student_number",studentNumber);
        }
        StudentNumberGroutid studentNumberGroutid = studentNumberGroutidService.getOne(studentNumberGroutidQueryWrapper);
        return Result.ok().data("studentCredit",studentNumberGroutid);
    }


    @ApiOperation("学分置换")
    @PostMapping("/creditReplacement")
    public Result creditReplacement(@RequestBody StudentCreditVo studentCreditVo){
        int trueCredit=studentCreditVo.getStudentCredit()-studentCreditVo.getTotal();
        QueryWrapper<StudentNumberGroutid> sngqw=new QueryWrapper<>();
        sngqw.eq("grout_id",studentCreditVo.getGroutId());
        sngqw.eq("student_number",studentCreditVo.getStudentNumber());
        StudentNumberGroutid studentNumberGroutid = studentNumberGroutidService.getOne(sngqw);
        //如果置换分数与实际分数相等，修改状态为已置换
        if (trueCredit==0){
           studentNumberGroutid.setIsorReplace(1);
           studentNumberGroutid.setAffirmCredit("0");
        }else {
        //如果置换分数小于实际分数修改实际分数
            studentNumberGroutid.setAffirmCredit(String.valueOf(trueCredit));
        }
        //将置换的课程代码与学生绑定
        List<Course> courseList = studentCreditVo.getCourseList();
        for (Course course : courseList) {
            StudentCourseNumber studentCourseNumber=new StudentCourseNumber();
            studentCourseNumber.setCourseNumber(course.getCourseNumber());
            studentCourseNumber.setStuNumber(studentCreditVo.getStudentNumber());
            studentCourseNumberService.save(studentCourseNumber);
        }
        boolean b = studentNumberGroutidService.updateById(studentNumberGroutid);
        if (b){
            return Result.ok().message("学分置换成功");
        }else {
            return Result.error("请重新置换");
        }
    }
}

